package org.ands.crosswalk;

import java.io.FileInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;

import org.ands.data.Contents;
import org.supercsv.cellprocessor.Optional;
import org.supercsv.cellprocessor.ParseBool;
import org.supercsv.cellprocessor.constraint.StrMinMax;
import org.supercsv.cellprocessor.ift.CellProcessor;
import org.supercsv.io.CsvBeanReader;
import org.supercsv.io.ICsvBeanReader;
import org.supercsv.prefs.CsvPreference;

// TODO: Auto-generated Javadoc
/**
 * The Class CrossWalkEntryRetrieverCSV.
 */
public class CrossWalkEntryRetrieverCSV implements ICrossWalkRetriever{
	
	
	
	/** The Constant CrossWalkEntryProcessor. */
	static final CellProcessor[] CrossWalkEntryProcessor = new CellProcessor[] {
        new StrMinMax(0, 1000),
        null,
        null,
        null,
        null,
        new Optional(new ParseBool()),
        null
    };
	
	/**
	 * Gets the crosswalk entry list from file.
	 *
	 * @param crosswalkFile the crosswalk file
	 * @param crossWalkEntryRetrieverCSV the cross walk entry retriever csv
	 * @return the crosswalk entry list from file
	 * @throws Exception the exception
	 */
	public ArrayList<CrossWalkEntry> getCrossWalkEntryListFromFile(final String crosswalkFile) throws Exception{
		assert(crosswalkFile != null);
		assert(!crosswalkFile.isEmpty());
		if((crosswalkFile != null) && (!crosswalkFile.isEmpty())){
			ArrayList<CrossWalkEntry> crossWalkEntryList = getCrossWalkEntryList(crosswalkFile);
			assert((crossWalkEntryList != null) && (!crossWalkEntryList.isEmpty()));
			return crossWalkEntryList;
		}
		
		assert(false);
		return null;
	}
	
	/**
	 * Reads one or more xpath-default-treepath combinations from a specified .csv file.
	 * Constructs a list of CrossWalkEntry objects from the values
	 *
	 * @param csvFileName the csv file name
	 * @return          		If successful, a list of CrossWalkEntry objects
	 * constructed from the values within the
	 * .csv file specified by <code>csvFileName</code>;
	 * <code>null</code> otherwise.
	 * @throws Exception the exception
	 * @see   	Contents
	 * @see 	ICsvBeanReader
	 * @since     1.0
	 */
	private ArrayList<CrossWalkEntry> getCrossWalkEntryList(
			final String csvFileName) 
					throws Exception{
		
		
		if((csvFileName == null) || (csvFileName.isEmpty())){
			throw new Exception("Requires valid csv filename");
		}

		InputStream inputStream = new FileInputStream(csvFileName);
		assert(inputStream != null);
		InputStreamReader reader = new InputStreamReader(inputStream);
		ICsvBeanReader beanReader = new CsvBeanReader(reader, CsvPreference.STANDARD_PREFERENCE);
		ArrayList<CrossWalkEntry> list = new ArrayList<CrossWalkEntry>();
		
		final String[] columnNames = beanReader.getCSVHeader(true);
		CrossWalkEntry crossWalkEntry;
		try{
			while ( (crossWalkEntry = beanReader.read(CrossWalkEntry.class, columnNames, CrossWalkEntryProcessor)) != null) {
				System.out.println("Adding crosswalk entry for xpath ["+crossWalkEntry.getXpath()+"].");
				list.add(crossWalkEntry);
			}
		}catch(Exception e){
			throw new Exception("ICsvBeanReader failed with exception ["+e.getMessage()+"] - your crosswalk ["+csvFileName+"] may have lines that do not conform with the cell processor rules");
		}
		
		if (list.size() <= 0){
			throw new Exception("No list of CrossWalkEntry created.");
		}
			
		return list;
		
	}
	
	

}


